home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / misc / emu / prlink_amiga.lha / prlink-0.8.0a / src / prserver.asm < prev    next >
Assembly Source File  |  1995-05-12  |  21KB  |  1,177 lines

  1.   .processor 6502
  2.   .include "options.inc"
  3.  
  4. #if target & c128
  5. host    = 128
  6. #endif
  7. #if target & c64
  8. host    = 64
  9. #endif
  10. #if target & vic20
  11. host    = 20
  12. #endif
  13. #if target & (pet3001 | pet4001)
  14. host    = 201    ; want 2001 but it must fit in a byte
  15. #endif
  16.  
  17. #if target & (c128 | c64)
  18. #if ramexp & piaexp
  19. pia    = $d7f0 ; the PIA base address.  See also the definition "bank".
  20. #endif
  21. #if ramexp & reuexp
  22. reu    = $df00 ; the REU base address.  See also the definition "bank".
  23. reubmin = $10    ; smallest bank number that refers to the REU banks
  24. #endif
  25. #endif
  26.  
  27. ; The machines with a VIA that use a VIA control line for handshaking
  28. ; must reset the interrupt flag before it can be used again.
  29.  
  30. clearviaifr = target & (vic20 | pet3001 | pet4001)
  31.  
  32. ; The following constant tells if the cable uses the PA2 handshaking line
  33.  
  34. pa2_used = cable & (pc64 | prlink | prlink88)
  35.  
  36.   seg MAIN
  37.   .org prsrv
  38.  
  39. #if target & (vic20 | c64 | c128)
  40. strval    = $10    ; strobe bit value on the Vic-20/C64/C128
  41.  
  42. start    = $ac    ; some memory locations
  43. end    = $ae
  44. cinv    = $314
  45. #endif
  46.  
  47. #if cable & (pc64 | c64net | transnib)
  48. #if target & (pet3001 | pet4001)
  49. stemp    = $bd    ; memory place that holds the byte that will be received
  50. #else
  51. stemp    = $a7    ; memory place that holds the byte that will be received
  52. #endif
  53. #endif
  54.  
  55. #if target & c128
  56. bstart    = $2d    ; start of basic program text
  57. bend    = $1210 ; end of basic program text
  58.  
  59. bank    = $a9    ; temporary variable that holds the memory bank
  60. stack    = $105    ; offset to the stack while in interrupt
  61.  
  62. peek    = $2a2
  63. peekptr = $2aa
  64. poke    = $2af
  65. pokeptr = $2b9
  66.  
  67. linkprg = $4f4f
  68. basrun    = $5aa6
  69.  
  70. ackval    = 4
  71. ack    = $dd00
  72. data    = $dd01
  73. ddr    = $dd03
  74. strobe    = $dd0d
  75. #endif
  76.  
  77. #if target & c64
  78. bstart    = $2b    ; start of basic program text
  79. bend    = $2d    ; end of basic program text
  80. #if ramexp
  81. bank    = $a9    ; temporary variable that holds the memory bank
  82. #else
  83. bank    = none    ; non-banked systems
  84. #endif
  85. blnsw    = $cc
  86. crsw    = $d0
  87.  
  88. stack    = $104    ; offset to the stack while in interrupt
  89.  
  90. clr    = $a659
  91. linkprg = $a533
  92. stxpt    = $a68e
  93. newstt    = $a7ae
  94.  
  95. ackval    = 4
  96. ack    = $dd00
  97. data    = $dd01
  98. ddr    = $dd03
  99. strobe    = $dd0d
  100. #endif
  101.  
  102. #if target & vic20
  103. bstart    = $2b    ; start of basic program text
  104. bend    = $2d    ; end of basic program text
  105. bank    = none
  106. blnsw    = $cc
  107. crsw    = $d0
  108.  
  109. stack    = $104    ; offset to the stack while in interrupt
  110.  
  111. clr    = $c659
  112. linkprg = $c533
  113. stxpt    = $c68e
  114. newstt    = $c7ae
  115.  
  116. ackval    = $20
  117. ack    = $911c
  118. data    = $9110
  119. ddr    = $9112
  120. strobe    = $911d
  121. #endif
  122.  
  123. #if target & (pet3001 | pet4001)
  124. start    = $c7    ;; the PET series
  125. end    = $c9
  126. cinv    = $0090
  127.  
  128. bstart    = $28    ; start of basic program text
  129. bend    = $2a    ; end of basic program text
  130. blnsw    = $a7
  131. crsw    = $ac
  132.  
  133. #if ramexp & pet96
  134. bank  = $bf    ; temporary variable that holds the memory bank
  135. latch = $fff0    ; write-only register
  136. #else
  137. bank    = none    ; non-banked systems
  138. #endif
  139.  
  140. stack = $104    ; offset to the stack while in interrupt
  141.  
  142. ackval    = $20    ; CB2 value bit when set to manual control
  143. ack    = $e84c ; VIA CRB
  144. data    = $e84f ; VIA PA without handshake
  145. ddr    = $e843 ; VIA DDRA
  146. strval    = $02    ; VIA CA1 bit in IFR
  147. strobe    = $e84d ; VIA IFR
  148. #endif
  149.  
  150. #if target & pet4001    ; for BASIC 4.0
  151. clr    = $b5e9
  152. linkprg = $b4b6
  153. stxpt    = $b622
  154. newstt    = $b74a
  155. #endif
  156. #if target & pet3001    ; for BASIC 2.0
  157. clr    = $c572
  158. linkprg = $c442
  159. stxpt    = $c5a7
  160. newstt    = $c6c4
  161. #endif
  162.  
  163. cmdinfo = 0    ; code for requesting machine type info
  164. cmdload = 1    ; code for loading
  165. cmdsave = 2    ; code for saving
  166. cmdjump = 3    ; code for jumping to an address
  167. cmdrun    = 4    ; code for running a BASIC program
  168.  
  169. mystart:    ; A jump table for external programs
  170.   jmp install        ; Installs the prserver wedge.
  171.   jmp deinstall     ; Removes the prserver wedge.
  172.   jmp send_switch    ; Switches to send configuration, and sends a byte.
  173.   jmp send        ; Sends a byte assuming send configuration.
  174.   jmp receive_switch    ; Switches to receive configuration, and receives a byte.
  175.   jmp receive        ; Receives a byte assuming receive configuration.
  176.   jsr install        ; Reinstalls the prserver wedge and
  177. #if target & c128    ; continues with the previous program.
  178.   jmp $ff33
  179. #else
  180.   pla
  181.   tay
  182.   pla
  183.   tax
  184.   pla
  185.   rti
  186. #endif
  187.  
  188. install:
  189.   sei
  190.   lda cinv    ; check the original IRQ vector
  191.   ldx cinv+1
  192.   cmp #<irq
  193.   bne irqinit
  194.   cpx #>irq
  195.   beq skipirq
  196. irqinit:    ; if it was different from our irq wedge, install the wedge
  197.   sta oldirq    ; first save the old IRQ vector
  198.   stx oldirq+1
  199.   lda #<irq    ; and then install ours
  200.   sta cinv
  201.   lda #>irq
  202.   sta cinv+1
  203. skipirq:
  204. #if ramexp & piaexp
  205. #if target & c128
  206.   lda #$3e
  207.   sta $ff00
  208. #endif
  209.   ldx #11    ; initialize the PIA
  210. 0$:
  211.   lda piatable-1,x
  212.   sta pia,x
  213.   dex
  214.   bne 0$
  215. #endif
  216. #if cable & (prlink | prlink88 | pc64)
  217. #if target & vic20
  218.   lda #$ef
  219.   and ack
  220.   sta ack    ; set CB1 to trigger on falling edge
  221. #endif
  222. #if target & (pet3001 | pet4001)
  223.   lda ack
  224.   and #%11111110; set CA1 to trigger on falling edge
  225.   ora #%11100000; set CB2 to output with manual control
  226.   sta ack
  227. #endif
  228. #endif
  229. #if cable & transnib
  230.   lda #$40    ; prepare for input: only DRCV is output
  231.   sta data    ; idle state of lines is high
  232.   sta ddr
  233. #endif
  234.   cli
  235.   rts
  236.  
  237. #if ramexp & piaexp
  238. piatable:
  239.   .byte $34,$fe,4,$ff,0,$ff,0,$dc,4,$fe,4
  240. #endif
  241.  
  242. irq:
  243. #if (target & c64) * pa2_used
  244.   lda #ackval    ; this is needed for Action Replay, whose fastload command
  245.   ora ack    ; resets the PA2 line
  246.   sta ack
  247. #endif
  248. #if cable & (prlink | prlink88)
  249.   lda #strval
  250.   bit strobe    ; check the -FLAG signal
  251.   beq return    ; jump if the client didn't want to send anything
  252.   ldx #0
  253.   stx ddr    ; restore the data lines to inputs
  254. #endif
  255. #if cable & pc64
  256.   lda #strval
  257.   bit strobe    ; check the -FLAG signal
  258.   beq return    ; jump if the client didn't want to send anything
  259.   ldx #$f
  260.   stx ddr    ; restore the data lines to inputs/outputs
  261. #endif
  262.  
  263. #if cable & c64net
  264.   lda data
  265.   and #$F8    ; check if the remote host wants to send a byte
  266.   eor #8
  267.   bne return    ; jump if not
  268.  
  269.   lda #$7
  270.   sta data
  271.   sta ddr
  272. #endif
  273.  
  274. #if cable & transnib
  275.   bit data    ; test if DRDY is low.
  276.   bmi return
  277.   lda #$40    ; prepare for input: only DRCV is output
  278.   sta data    ; idle state of lines is high
  279.   sta ddr
  280. #endif
  281.  
  282.   jsr rereceive ; receive byte without requiring handshaking
  283.   cmp #cmdinfo
  284.   bne load    ; branch if the client did not request for host info
  285.   lda #host    ; return the host info byte
  286.   jsr send_switch
  287.   lda #<mystart ; tell the driver start address
  288.   jsr send
  289.   lda #>mystart
  290.   jsr send
  291.   lda bstart    ; and the BASIC start address
  292.   jsr send
  293.   lda bstart+1
  294.   jsr send
  295.  
  296. return:
  297. oldirq = * + 1
  298.   jmp *     ; continue the normal irq (selfmodifying code)
  299.  
  300. load:
  301.   cmp #cmdload    ; was it the command for loading?
  302.   beq 0$
  303.   jmp jump    ; no, skip
  304.  
  305. 0$:
  306.   jsr gethdr    ; get the addresses
  307. #if bank
  308.   lda bank    ; other bank than the default specified => can't be basic
  309.   bne 1$
  310. #endif
  311.   lda start    ; check if it is a basic program
  312.   eor bstart
  313.   bne 1$
  314.   lda start+1
  315.   eor bstart+1
  316. 1$:
  317.   pha        ; accu is 0 if it is a basic program
  318. #if target & (c64 | c128)
  319.   lda $d011
  320.   pha
  321.   lda $d030
  322.   pha
  323.   lda #$1
  324.   sta $d011    ; blank the screen
  325.   sta $d030    ; switch to 2 MHz mode
  326. #endif
  327.  
  328. #if ramexp & reuexp
  329.   lda bank
  330.   cmp #reubmin    ; is it a REU bank?
  331.   bcc 14$    ; no, do not save REC registers on stack
  332.  
  333. #if actionreuplay
  334.   lda #$2a
  335.   sta $de00    ; enable Action Replay RAM at $df00 (disable the ROM)
  336.         ; Action Replay has one write-only I/O register at $de00-$deff.
  337.         ; Its bits are as follows:
  338.         ; 7 - not used
  339.         ; 6 - probably resets the IRQ/NMI flipflop in the freezer mode
  340.         ; 5 - enables RAM at I/O2
  341.         ; 4 - bank selector
  342.         ; 3 - bank selector
  343.         ; 2 - 1=cartridge off
  344.         ; 1 - 1=-EXROM high
  345.         ; 0 - 1=-GAME low
  346. #else
  347.   ldx #10
  348. 11$:
  349.   lda reu,x
  350.   pha
  351.   dex
  352.   bne 11$
  353. #endif
  354.   lda end+1    ; store the end of file pointer high byte
  355.   pha
  356.   jsr reuinit    ; initialize the REU registers.  C flag is set at this stage.
  357. 12$:
  358.   jsr receive
  359.   sta (start),y
  360.   jsr incmptreu
  361.   bne 12$
  362.  
  363.   dec $d030    ; switch to 1 MHz mode
  364.   lda #$f2
  365.   sta reu+1    ; swap the REU memory back
  366.   pla
  367.   sta start+1    ; adjust the end address pointers
  368.   sta end+1
  369.  
  370. #if actionreuplay
  371.   lda #$0a
  372.   sta $de00    ; restore normal Action Replay configuration
  373. #else
  374.   ldx #0
  375. 13$:
  376.   inx
  377.   pla
  378.   sta reu,x
  379.   cpx #10
  380.   bne 13$
  381. #endif
  382.   jmp endload
  383. 14$:
  384. #endif
  385.  
  386. #if ramexp & piaexp
  387.   lda end+1    ; store the end of file pointer high byte
  388.   pha
  389.   lda pia    ; store the PIA memory configuration
  390.   pha
  391. #if target & c128
  392.   lda $d506    ; store the common memory configuration
  393.   pha
  394. #endif
  395.   jsr piainit    ; initialize the PIA expansion (with $d506 value in A)
  396. 2$:
  397.   jsr receive
  398.   sta (start),y
  399.   jsr incmptr
  400.   bne 2$
  401.  
  402. #if target & c128
  403.   pla        ; restore the original MMU banking
  404.   ldx #0    ; enable all ROMs, select RAM bank 0
  405.   stx $d500
  406.   sta $d506    ; restore the common memory configuration
  407. #endif
  408.   pla
  409.   sta pia
  410.   pla
  411.   sta start+1    ; adjust the end address pointers
  412.   sta end+1
  413. #else
  414. #if target & c128
  415.   lda pokeptr
  416.   pha
  417.   lda #start
  418.   sta pokeptr
  419.  
  420. 2$:
  421.   jsr receive    ; get the bytes
  422.   ldx bank
  423.   jsr poke
  424.   jsr incmptr    ; update the pointer
  425.   bne 2$
  426.  
  427.   sty bank
  428.   pla
  429.   sta pokeptr
  430. #else
  431. 2$:
  432.   jsr receive    ; get the bytes
  433.   sta (start),y
  434.   jsr incmptr    ; update the pointer
  435.   bne 2$
  436. #endif
  437. #endif
  438.  
  439. endload:
  440. #if target & (c64 | c128)
  441.   pla
  442.   sta $d030    ; restore original speed
  443.   pla
  444.   sta $d011    ; and screen mode
  445. #endif
  446.  
  447.   pla
  448.   bne 0$    ; it was not a basic program
  449.   lda end    ; set the basic end address
  450.   sta bend
  451.   lda end+1
  452.   sta bend+1
  453.   jsr linkprg    ; relink the program
  454. #if target & c128
  455.   lda #0
  456.   sta $ff00    ; restore the MMU configuration (linkprg changes it)
  457. #endif
  458. 0$:
  459.   jmp (oldirq)
  460.  
  461. jump:
  462.   cmp #cmdjump    ; was it the command for jumping?
  463.   bne save    ; no, skip
  464.  
  465.   jsr receive    ; get the memory configuration (for the c128)
  466. #if target & c128
  467.   sta bank    ; and temporarily store it
  468. #endif
  469.   jsr receive    ; get the jump address low
  470.   tax
  471.   jsr receive    ; get the jump address high
  472.   pha        ; and store it
  473.   txa
  474.   pha        ; store the jump address low
  475.   lda #0
  476.   pha        ; clear the flags
  477.   pha        ; and the registers
  478.   pha
  479.   pha
  480. #if target & c128
  481.   lda bank
  482.   pha        ; store the MMU configuration
  483. #endif
  484.   jsr deinstall ; deinstall the IRQ routine
  485. #if target & c128
  486. #else
  487.   sta crsw    ; turn the cursor off
  488.   sta blnsw
  489. #endif
  490.   jmp (oldirq)
  491.  
  492. save:
  493.   cmp #cmdsave
  494.   bne run
  495.  
  496. #if target & (c64 | c128)
  497.   lda $d011
  498.   pha
  499.   lda $d030
  500.   pha
  501.   lda #$1
  502.   sta $d011    ; blank the screen
  503.   sta $d030    ; switch to 2 MHz mode
  504. #endif
  505.  
  506.   jsr gethdr    ; get the pointers
  507.  
  508. #if ramexp & reuexp
  509.   lda bank
  510.   cmp #reubmin    ; is it a REU bank?
  511.   bcc 14$    ; no, jump to normal save
  512.  
  513. #if actionreuplay
  514.   lda #$2a
  515.   sta $de00    ; disable Action ROM at $df00
  516. #else
  517.   ldx #10
  518. 11$:
  519.   lda reu,x    ; store the REU registers
  520.   pha
  521.   dex
  522.   bne 11$
  523. #endif
  524.   lda end+1    ; store the end of file pointer high byte
  525.   pha
  526.   jsr reuinit    ; initialize the REU registers.  C flag is set at this stage.
  527. 12$:
  528.   lda (start),y
  529.   jsr send
  530.   jsr incmptreu
  531.   bne 12$
  532.  
  533.   dec $d030    ; switch to 1 MHz mode
  534.   lda #$f2
  535.   sta reu+1    ; swap the REU memory back
  536.   pla
  537.   sta start+1
  538.   sta end+1
  539.  
  540. #if actionreuplay
  541.   lda #$0a
  542.   sta $de00    ; restore normal Action Replay configuration
  543. #else
  544.   ldx #0
  545. 13$:
  546.   inx
  547.   pla
  548.   sta reu,x
  549.   cpx #10
  550.   bne 13$
  551. #endif
  552.   jmp endsave
  553. 14$:
  554. #endif
  555.  
  556. #if ramexp & piaexp
  557.   lda pia    ; store the PIA memory configuration
  558.   pha
  559. #if target & c128
  560.   lda $d506    ; store the common memory configuration
  561.   pha
  562. #endif
  563.   jsr piainit    ; initialize the PIA expansion (with $d506 value in A)
  564. 0$:
  565.   lda (start),y
  566.   jsr send
  567.   jsr incmptr
  568.   bne 0$
  569.  
  570. #if target & c128
  571.   pla
  572.   ldx #0
  573.   stx $d500
  574.   sta $d506
  575. #endif
  576.   pla
  577.   sta pia
  578. #else
  579. #if target & c128
  580.   lda peekptr
  581.   pha
  582.   lda #start
  583.   sta peekptr
  584.  
  585. 0$:
  586.   ldx bank
  587.   jsr peek
  588.   jsr send
  589.   jsr incmptr
  590.   bne 0$
  591.  
  592.   sty bank
  593.   pla
  594.   sta peekptr
  595. #else
  596. #if target & c64
  597.   ldx 1
  598. 0$:
  599.   lda #$34
  600.   sta 1     ; switch to 64 kB RAM config
  601.   lda (start),y
  602.   stx 1     ; restore the normal config
  603. #else
  604. 0$:
  605.   lda (start),y
  606. #endif
  607.   jsr send
  608.   jsr incmptr
  609.   bne 0$
  610. #endif
  611. #endif
  612.  
  613. endsave:
  614. #if target & (c64 | c128)
  615.   pla
  616.   sta $d030    ; restore original speed
  617.   pla
  618.   sta $d011    ; and screen mode
  619. #endif
  620. return2:
  621.   jmp (oldirq)    ; return from interrupt
  622.  
  623. run:
  624.   cmp #cmdrun
  625.   bne return2
  626.  
  627.   jsr deinstall ; Install the original interrupt routine
  628. #if target & c128
  629.   cli        ; process the pending interrupt in a very kludgeous manner.
  630.   jmp basrun
  631. #else
  632.   sta crsw    ; turn the cursor off
  633.   sta blnsw
  634.   cli        ; process the pending interrupt in a very kludgeous manner.
  635.   jsr clr    ; The stack won't run out, since the BASIC clr call
  636.         ; initializes the stack pointer.
  637.   jsr stxpt    ; Set the BASIC text pointer (to the beginning of the prg)
  638.   jmp newstt    ; BASIC warm start
  639. #endif
  640.  
  641. deinstall:    ; restore the original interrupt routine
  642.   lda oldirq
  643.   sta cinv
  644.   lda oldirq+1
  645.   sta cinv+1
  646.   rts
  647.  
  648. gethdr:
  649.   jsr receive    ; get the memory bank byte
  650. #if ramexp
  651.   sta bank
  652. #else
  653. #if target & c128
  654.   lsr
  655.   ror
  656.   ror
  657.   ora #$3f
  658.   sta bank
  659. #endif
  660. #endif
  661.   lda #0    ; send the acknowledgement code 0
  662.   jsr send_switch
  663.   jsr receive_switch ; get the file start and end vectors
  664.   sta start
  665.   jsr receive
  666.   sta start+1
  667.   jsr receive
  668.   sta end
  669.   jsr receive
  670.   sta end+1
  671.   rts
  672.  
  673. #if ramexp & piaexp
  674. incmptr:    ; increment and compare the current byte pointer
  675.   inc start    ; and change the PIA bank if necessary.
  676.   bne 0$
  677.   inc start+1
  678.   bpl 0$
  679.   dex        ; decrease the bank jump counter
  680.   lda #$40
  681.   sta start+1    ; restore the address
  682.   clc
  683.   lda #$10
  684.   adc pia
  685.   sta pia    ; and adjust the PIA bank
  686. 0$:
  687.   txa        ; is it the last bank?
  688.   bne 1$    ; no, return
  689.   lda start    ; perform the comparison
  690.   cmp end
  691.   bne 1$
  692.   lda start+1
  693.   cmp end+1
  694. 1$:
  695.   rts
  696. #else
  697. incmptr:    ; increment and compare the current byte pointer.
  698.   inc start    ; increment.
  699.   bne 0$
  700.   inc start+1
  701. 0$:
  702.   lda start    ; compare.  if start == end, the zero flag will be set.
  703.   cmp end
  704.   bne 1$
  705.   lda start+1
  706.   cmp end+1
  707. 1$:
  708.   rts
  709. #endif
  710.  
  711. #if ramexp & reuexp
  712. incmptreu:
  713.   inc start    ; increment and compare the current byte pointer
  714.   bne 0$    ; and transfer another REU block in if necessary.
  715.   inc start+1
  716.   bpl 0$
  717.   dex        ; decrease the bank jump counter
  718.   dec $d030    ; slow down to 1 MHz
  719.   lda #$f2
  720.   sta reu+1    ; swap the buffers
  721.   lda #$40
  722.   sta start+1    ; restore the REU buffer address
  723.   clc
  724. #if actionreuplay
  725.   adc bank
  726.   sta bank
  727. #else
  728.   adc reu+5
  729. #endif
  730.   sta reu+5    ; update the REU memory pointer
  731.   lda #$f2
  732.   sta reu+1    ; swap the buffers
  733.   inc $d030    ; switch back to 2 MHz mode
  734. 0$:
  735.   txa        ; is it the last bank?
  736.   bne 1$    ; no, return
  737.   lda start    ; perform the comparison
  738.   cmp end
  739.   bne 1$
  740.   lda start+1
  741.   cmp end+1
  742. 1$:
  743.   rts
  744. #endif
  745.  
  746. #if cable & (prlink | prlink88)
  747.  
  748.   ; .A := data, .Y := 00, .X preserved
  749. receive_switch:
  750.         ;;; wait for first part of handshake
  751.   lda #strval
  752. 1$:
  753.   bit strobe    ; wait for handshaking
  754.   beq 1$
  755. #if clearviaifr
  756.   sta strobe
  757. #endif        ; clearviaifr
  758.  
  759.         ;;; and only then switch data direction.
  760.   lda #0    ; switch back to inputs
  761.   sta ddr
  762.  
  763.   beq receive1    ; branch always
  764.  
  765. receive:
  766. #if clearviaifr
  767. rereceive:    ; rereceive (without handshake) is only different for the CIA
  768. #endif
  769.   lda #strval
  770. 0$:
  771.   bit strobe    ; wait for handshaking
  772.   beq 0$
  773. #if clearviaifr
  774.   sta strobe
  775. #else
  776. rereceive:    ; rereceive (receive without handshaking) for the CIA
  777. #endif        ; clearviaifr
  778. receive1:
  779.   lda #ackval
  780.   eor ack
  781.   ldy data    ; read the byte
  782.   sta ack    ; acknowledge
  783.   tya
  784.   ldy #0
  785.   rts
  786.  
  787.   ; .A trashed, .Y := 00, .X preserved
  788. send_switch:
  789.         ;;; wait for first part of handshake
  790.   tay
  791.   lda #strval
  792. 1$:
  793.   bit strobe    ; wait for handshaking
  794.   beq 1$
  795. #if clearviaifr
  796.   sta strobe
  797. #endif
  798.         ;;; and only then switch data direction.
  799. #if cable & prlink88
  800.   lda #$ff
  801. #else
  802.   lda #$0f
  803. #endif
  804.   sta ddr    ; set the data lines to output
  805.   bne send1    ; branch always
  806.  
  807. send:
  808.   tay
  809.   lda #strval
  810. 0$:
  811.   bit strobe    ; wait for handshaking
  812.   beq 0$
  813. #if clearviaifr
  814.   sta strobe
  815. #endif
  816. send1:
  817. #if cable & prlink88
  818. #else
  819.   tya
  820.   sta data    ; send the low nybble
  821.   lsr
  822.   lsr
  823.   lsr
  824.   lsr
  825.   tay        ; move the high nybble to y
  826.   lda #ackval
  827.   eor ack
  828.   sta ack    ; ack: the low nybble is on the bus
  829.   lda #strval
  830. 1$:
  831.   bit strobe    ; handshake
  832.   beq 1$
  833. #if clearviaifr
  834.   sta strobe
  835. #endif        ; via
  836. #endif        ; prlink88
  837.   sty data    ; send the high nybble (or the whole byte, for prlink88)
  838.   ldy #0
  839.   lda ack
  840.   eor #ackval
  841.   sta ack    ; ack: the high nybble is on the bus
  842.   rts
  843.  
  844. #endif        ; prlink | prlink88
  845.  
  846. #if cable & pc64
  847.  
  848.   ; .A := data, .Y := 00, .X preserved
  849. receive_switch:
  850. receive:
  851. #if clearviaifr
  852. rereceive:
  853. #endif
  854.   lda #strval
  855. 0$:
  856.   bit strobe    ; wait for handshaking
  857.   beq 0$
  858. #if clearviaifr
  859.   sta strobe
  860. #else
  861. rereceive:
  862. #endif
  863.   lda ack
  864.   and #255 - ackval
  865.   ldy data
  866.   sta ack
  867.   tya
  868.   lsr
  869.   lsr
  870.   lsr
  871.   lsr
  872.   sta stemp
  873.   lda #strval
  874. 1$:
  875.   bit strobe
  876.   beq 1$
  877. #if clearviaifr
  878.   sta strobe
  879. #endif
  880.   lda ack
  881.   ora #ackval
  882.   tay
  883.   lda data
  884.   sty ack
  885.   and #$F0
  886.   ora stemp
  887.   ldy #0
  888.   rts
  889.  
  890.   ; .A trashed, .Y := 00, .X preserved
  891. send_switch:
  892. send:
  893.   tay
  894.   lda #strval
  895. 0$:
  896.   bit strobe    ; wait for handshaking
  897.   beq 0$
  898. #if clearviaifr
  899.   sta strobe
  900. #endif
  901.   sty data
  902.   lda ack
  903.   and #255 - ackval
  904.   sta ack
  905.   tya
  906.   lsr
  907.   lsr
  908.   lsr
  909.   lsr
  910.   tay
  911.   lda #strval
  912. 1$:
  913.   bit strobe    ; wait for handshaking
  914.   beq 1$
  915. #if clearviaifr
  916.   sta strobe
  917. #endif
  918.   sty data
  919.   lda ack
  920.   ora #ackval
  921.   sta ack
  922.   ldy #0
  923.   rts
  924.  
  925. #endif        ; pc64
  926.  
  927. #if cable & c64net
  928.  
  929.   ; .A := data, .Y := 00, .X preserved
  930. receive_switch:
  931. receive:
  932. rereceive:
  933.   lda #8
  934. 0$:
  935.   bit data    ; initial handshaking
  936.   beq 0$
  937.   lda data    ; get the high nybble
  938.   and #$f0
  939.   sta stemp
  940.   lda #8
  941.   sta data    ; acknowledge (place 0 on PB2)
  942. 1$:
  943.   bit data    ; wait for acknowledgement
  944.   bne 1$
  945.   ldy #4
  946.   lda data    ; get the low nybble
  947.   sty data    ; acknowledge
  948.   ldy #0
  949.   lsr
  950.   lsr
  951.   lsr
  952.   lsr
  953.   ora stemp
  954.   rts
  955.  
  956.   ; .A trashed, .Y := 00, .X preserved
  957. send_switch:    ; switch to sending and send
  958. send:
  959.   tay
  960. 0$:
  961.   lda data    ; initial handshaking
  962.   and #$f8
  963.   eor #$f0
  964.   bne 0$
  965.   lda #0
  966.   sta data
  967. 1$:
  968.   lda data
  969.   bne 1$
  970.   tya
  971.   ora #4
  972.   sta data    ; send the lowest bit pair
  973.   lda #8
  974. 2$:
  975.   bit data    ; wait for acknowledgement
  976.   beq 2$
  977.   tya
  978.   lsr
  979.   lsr
  980.   tay
  981.   and #3
  982.   sta data    ; send the lowest bit pair but one
  983.   lda #8
  984. 3$:
  985.   bit data    ; wait for acknowledgement
  986.   bne 3$
  987.   tya
  988.   lsr
  989.   lsr
  990.   tay
  991.   ora #4
  992.   sta data    ; send the highest bit pair but one
  993.   lda #8
  994. 4$:
  995.   bit data    ; wait for acknowledgement
  996.   beq 4$
  997.   tya
  998.   lsr
  999.   lsr
  1000.   sta data    ; send the highest bit pair
  1001.   lda #8
  1002. 5$:
  1003.   bit data    ; wait for acknowledgement
  1004.   bne 5$
  1005.   lda #4
  1006.   sta data
  1007.   ldy #0
  1008.   rts
  1009.  
  1010. #endif        ; pc64
  1011.  
  1012. #if cable & transnib
  1013.  
  1014.   ; .A := data, .Y := 00, .X preserved
  1015. receive_switch:
  1016.   lda #$40    ; $40 is DRCV (output), $80 is DRDY (input)
  1017.   sta ddr
  1018. receive:
  1019. rereceive:
  1020.   jsr recvnyb    ; high nybble first
  1021.   asl
  1022.   asl
  1023.   asl
  1024.   asl
  1025.   sta stemp
  1026.   jsr recvnyb
  1027.   ldy #0    ; (y is preserved in this function)
  1028.   ora stemp
  1029.   rts
  1030.  
  1031. recvnyb:
  1032. rdrdyhi:
  1033.   bit data    ; - Receiver starts waiting for DRDY to go low.
  1034.   bmi rdrdyhi
  1035.         ; - Sender puts nybble on data lines, pulls DRDY low and waits
  1036.         ; for DRCV to go low.
  1037.   lda data    ; - Receiver gets nybble,
  1038.   and #$ff-$40    ;   pulls DRCV low
  1039.   sta data
  1040. rdrdylo:
  1041.   bit data    ;   and waits for DRDY to go high.
  1042.   bpl rdrdylo
  1043.         ; - Sender pulls DRDY high and waits for DRCV to go high.
  1044.   ora #$40
  1045.   sta data    ; - Receiver pulls DRCV high
  1046.   and #$0f
  1047.   rts
  1048.  
  1049.   ; .A trashed, .Y := 00, .X preserved
  1050. send_switch:
  1051.   ldy #$4f    ; $80 is DRCV (input), $40 is DRDY (output)
  1052.   sty ddr    ; note that the names are swapped from receiving but the
  1053.         ; data direction isn't!
  1054. send:
  1055.   tay        ; high nybble first
  1056.   lsr
  1057.   lsr
  1058.   lsr
  1059.   lsr
  1060.   jsr sendnyb
  1061.   tya
  1062.   and #$0f    ; fall through to send low nybble
  1063.   ldy #0    ; clear y
  1064.  
  1065. sendnyb:    ; - Receiver starts waiting for DRDY to go low.
  1066.   sta data    ; - Sender puts nybble on data lines, pulls DRDY low and
  1067. rdrcvhi:
  1068.   bit data    ;   waits or DRCV to go low.
  1069.   bmi rdrcvhi
  1070.         ; - Receiver gets nybble, pulls DRCV low
  1071.         ;   and waits for DRDY to go high.
  1072.   ora #$40    ; - Sender pulls DRDY high and
  1073.   sta data
  1074. rdrcvlo:
  1075.   bit data    ;   waits for DRCV to go high.
  1076.   bpl rdrcvlo
  1077.  
  1078.   rts
  1079.  
  1080. #endif
  1081.  
  1082. #if ramexp & piaexp
  1083. piainit:
  1084. #if target & c128
  1085.   ora #$3f    ; the accu must be loaded with $d506 when calling this routine
  1086.   sta $d506    ; set the MMU configuration to 32kB common memory (top and low)
  1087.   lda bank
  1088.   and #$f
  1089.   lsr
  1090.   ror
  1091.   ror
  1092.   tax
  1093.   and #$c0
  1094.   ora #2
  1095.   sta $d500    ; set the MMU banking (disabling the BASIC ROM)
  1096.   txa
  1097.   ror
  1098.   ror
  1099. #else
  1100.   lda bank
  1101.   asl
  1102.   asl
  1103.   asl
  1104.   asl
  1105. #endif
  1106.   eor #$c0
  1107.   and #$c0
  1108.   ora #$c
  1109.   sta pia    ; store the PIA banking configuration
  1110.   lda start+1
  1111.   lsr
  1112.   lsr
  1113.   and #$30
  1114.   ora pia
  1115.   sta pia    ; set the initial PIA configuration
  1116. #endif
  1117. #if ramexp
  1118. rptrinit:
  1119.   sec
  1120.   lda end+1
  1121.   ora #$3f
  1122.   sbc start+1    ; get the amount of bank crossings
  1123.   asl
  1124.   rol
  1125.   rol
  1126.   and #3
  1127.   tax        ; and store it to x
  1128.   bne 0$    ; check for address wraparound
  1129.   lda start
  1130.   cmp end    ; if start >= end, the amount of bank crossings will be 4.
  1131.   lda start+1
  1132.   sbc end+1
  1133.   bcc 0$
  1134.   ldx #4
  1135. 0$:
  1136.   lda start+1
  1137.   and #$3f
  1138.   ora #$40
  1139.   sta start+1
  1140.   lda end+1
  1141.   and #$3f
  1142.   ora #$40
  1143.   sta end+1
  1144.   rts
  1145. #endif
  1146.  
  1147. #if ramexp & reuexp
  1148. reuinit:
  1149.   lda #0
  1150.   ldx #$40
  1151.   sta reu+2    ; set the buffer address for the C64/C128
  1152.   stx reu+3
  1153.   sta reu+7    ; set the buffer length
  1154.   stx reu+8
  1155.   sta reu+9    ; reset some other registers
  1156.   sta reu+10
  1157.   lda bank
  1158.   sbc #reubmin    ; set the memory bank (C flag initially set)
  1159.   sta reu+6
  1160.   lda start    ; set the start address in the REU
  1161.   sta reu+4
  1162.   lda start+1
  1163.   sta reu+5
  1164. #if actionreuplay
  1165.   sta bank
  1166. #endif
  1167. #if target & c128
  1168.   lda #2
  1169.   sta $ff00    ; switch to RAM bank 0 and disable the BASIC ROM
  1170. #endif
  1171.   dec $d030    ; slow down to 1 MHz
  1172.   lda #$f2
  1173.   sta reu+1    ; swap the buffers
  1174.   inc $d030    ; speed up again
  1175.   jmp rptrinit
  1176. #endif
  1177.